#ifndef EMS_PROTOCOL_PROTOCOL_INTERFACE_H
#define EMS_PROTOCOL_PROTOCOL_INTERFACE_H

#include <string>
#include <vector>
#include <cstdint>

namespace ems {
namespace protocol {

enum class ProtocolType {
    MODBUS_RTU,
    MODBUS_TCP,
    MQTT
};

enum class DataType {
    UINT16,
    INT16,
    UINT32,
    INT32,
    FLOAT32,
    UINT64,
    INT64,
    FLOAT64
};

enum class RegisterType {
    HOLDING_REGISTER,
    INPUT_REGISTER,
    COIL,
    DISCRETE_INPUT
};

struct RegisterData {
    uint16_t address;
    uint16_t length;
    std::vector<uint16_t> values;
    uint64_t timestamp;
    bool valid;
    
    RegisterData() : address(0), length(0), timestamp(0), valid(false) {}
};

class ProtocolInterface {
public:
    virtual ~ProtocolInterface() = default;
    
    virtual bool connect() = 0;
    virtual void disconnect() = 0;
    virtual bool isConnected() const = 0;
    
    virtual bool readHoldingRegisters(uint16_t address, uint16_t count, std::vector<uint16_t>& data) = 0;
    virtual bool readInputRegisters(uint16_t address, uint16_t count, std::vector<uint16_t>& data) = 0;
    virtual bool readCoils(uint16_t address, uint16_t count, std::vector<bool>& data) = 0;
    virtual bool readDiscreteInputs(uint16_t address, uint16_t count, std::vector<bool>& data) = 0;
    
    virtual bool writeSingleRegister(uint16_t address, uint16_t value) = 0;
    virtual bool writeMultipleRegisters(uint16_t address, const std::vector<uint16_t>& values) = 0;
    virtual bool writeSingleCoil(uint16_t address, bool value) = 0;
    virtual bool writeMultipleCoils(uint16_t address, const std::vector<bool>& values) = 0;
    
    virtual std::string getLastError() const = 0;
    virtual ProtocolType getType() const = 0;
};

}  // namespace protocol
}  // namespace ems

#endif  // EMS_PROTOCOL_PROTOCOL_INTERFACE_H